package module.map.scenes
{
	import drongo.desktop.menu.MenuHelper;
	import drongo.desktop.utils.CollisionsHelp;
	import drongo.model.events.ModelEvent;
	import drongo.model.propertys.ArrayProperty;
	import drongo.model.values.CollectionValue;
	
	import flash.display.NativeMenu;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.engine.BreakOpportunity;
	import flash.ui.Keyboard;
	
	import common.view.FGUIMediator;
	
	import fairygui.GComponent;
	import fairygui.GRoot;
	
	import module.map.Operations;
	import module.map.model.MapModel;
	import module.map.model.NodeTypes;
	import module.map.model.ProjectModel;
	import module.map.model.Propertys;
	import module.map.nodes.newNode.NewNodeWindow;
	
	import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap;
	
	import ui.Map.UI_AreaNodeView;
	import ui.Map.UI_ImageNodeView;
	import ui.Map.UI_PathNodeView;
	import ui.Map.UI_ScenePanel;
	import ui.Map.UI_TowerNodeView;
	
	public class SceneMediator extends FGUIMediator
	{
		[Inject]
		public var view:UI_ScenePanel;
		[Inject]
		public var project:ProjectModel;
		[Inject]
		public var mediatorMap:IMediatorMap;
		//flashStage
		private var stage:Stage;
		//右键菜单
		private var rightMenu:NativeMenu;
		//当前地图
		private var currentMap:MapModel;
		
		private var contentStartPoint:Point=new Point();
		private var startPoint:Point=new Point();
		private var endPoint:Point=new Point();
		
		private var testLayer:TestLayer;
		public function SceneMediator()
		{
			super();
		}
		
		override public function initialize():void{
			super.initialize();
			this.stage=this.view.displayObject.stage;
			
			this.testLayer=new TestLayer(this.project);
			this.view.m_content.m_testLayer.displayListContainer.addChild(this.testLayer);
			
			this.SwitchMapHandler();
			this.RefreshNodeList();
			this.AddEvents();
		}
		
		override public function destroy():void{
			super.destroy();
			this.RemoveEvents();
		}
		
		private function AddEvents():void{
			this.view.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN,this.RightMouseDownHandler);
			this.project.addEventListener(Event.CHANGE,SwitchMapHandler);
			this.view.m_background.addEventListener(MouseEvent.MOUSE_DOWN,this.MouseDownHandler);
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,this.KeyboardDownHandler);
		}
		
		private function RemoveEvents():void{
			this.view.removeEventListener(MouseEvent.RIGHT_CLICK,this.RightMouseDownHandler);
			this.project.removeEventListener(Event.CHANGE,SwitchMapHandler);
			this.view.m_background.removeEventListener(MouseEvent.MOUSE_DOWN,this.MouseDownHandler);
			this.stage.removeEventListener(KeyboardEvent.KEY_DOWN,this.KeyboardDownHandler);
		}
		
		private function KeyboardDownHandler(e:KeyboardEvent):void{
			if(e.keyCode==Keyboard.DELETE){
				if(!this.currentMap){
					return;
				}
				if(this.currentMap.selector.selectedList.length==0){
					return;
				}
				var isEdiatorPoint:Boolean;
				var nodes:ArrayProperty=this.currentMap.Get(Propertys.NODES) as ArrayProperty;
				var node:CollectionValue;
				for (var i:int = 0; i < nodes.length; i++) 
				{
					node=nodes.GetAt(i) as CollectionValue;
					isEdiatorPoint=node.Get(Propertys.EDIATRO_MODE).GetValue()>0;
					if(isEdiatorPoint){
						break
					}
				}
				if(isEdiatorPoint){
					return;
				}
				this.project.undoSystem.executeOperation(Operations.DELETE_NODE);
			}
		}
		
		private function RightMouseDownHandler(e:MouseEvent):void{
			if(this.project.currentMap==null){
				return;
			}
			this.startPoint.x=this.stage.mouseX;
			this.startPoint.y=this.stage.mouseY;
			this.contentStartPoint.x=this.view.m_content.x;
			this.contentStartPoint.y=this.view.m_content.y;
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE,this.RightMouseMoveHandler);
			stage.addEventListener(MouseEvent.RIGHT_MOUSE_UP,this.RightMouseUpHandler);
		}
		
		private function RightMouseMoveHandler(e:MouseEvent):void{
			this.endPoint.x=this.stage.mouseX;
			this.endPoint.y=this.stage.mouseY;
			this.view.m_content.x=this.contentStartPoint.x+(this.endPoint.x-this.startPoint.x);
			this.view.m_content.y=this.contentStartPoint.y+(this.endPoint.y-this.startPoint.y);
		}
		
		private function RightMouseUpHandler(e:MouseEvent):void{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.RightMouseMoveHandler);
			stage.removeEventListener(MouseEvent.RIGHT_MOUSE_UP,this.RightMouseUpHandler);
			
			this.endPoint.x=this.stage.mouseX;
			this.endPoint.y=this.stage.mouseY;
			if(CollisionsHelp.DistanceDetection(this.startPoint,this.endPoint,2)){
				this.ShowMenu(this.stage.mouseX,this.stage.mouseY);
			}else{
				this.view.m_content.x=this.contentStartPoint.x+(this.endPoint.x-this.startPoint.x);
				this.view.m_content.y=this.contentStartPoint.y+(this.endPoint.y-this.startPoint.y);
			}
		}
		
		private function MouseDownHandler(e:MouseEvent):void{
			if(this.project.currentMap){
				this.project.currentMap.selector.resetSelectList();
			}
		}
		
		//切换地图
		private function SwitchMapHandler(e:Event=null):void{
			if(this.currentMap){
				this.currentMap.removeEventListener(ModelEvent.CHILD_VALUE_CHANGED,this.MapPropertyChanged);
				this.currentMap.nodes.removeEventListener(ModelEvent.ADD_CHILD,this.NodeAddHandler);
				this.currentMap.nodes.removeEventListener(ModelEvent.REMOVE_CHILD,this.NodeRemoveHandler);
			}
			this.currentMap=this.project.currentMap;
			if(this.currentMap){
				this.currentMap.addEventListener(ModelEvent.CHILD_VALUE_CHANGED,this.MapPropertyChanged);
				this.currentMap.nodes.addEventListener(ModelEvent.ADD_CHILD,this.NodeAddHandler);
				this.currentMap.nodes.addEventListener(ModelEvent.REMOVE_CHILD,this.NodeRemoveHandler);
			}
			this.RefreshView();
			this.RefreshNodeList();
		}
		
		private function RefreshView():void{
			if(this.currentMap==null){
				return;
			}
			var w:Number=this.currentMap.Get(Propertys.WIDTH).GetValue();
			var h:Number=this.currentMap.Get(Propertys.HEIGTH).GetValue();
			
			var pw:Number=this.currentMap.Get(Propertys.NAV_WIDTH).GetValue();
			var ph:Number=this.currentMap.Get(Propertys.NAV_HEIGTH).GetValue();
			
			this.view.m_content.m_background.x=pw;
			this.view.m_content.m_background.y=ph;
			this.view.m_content.m_background.width=w;
			this.view.m_content.m_background.height=h;
			
			this.view.m_content.m_content.x=pw;
			this.view.m_content.m_content.y=ph;
			
			this.view.m_content.m_physics.x=0;
			this.view.m_content.m_physics.y=0;
			this.view.m_content.m_physics.width=w+pw*2;
			this.view.m_content.m_physics.height=h+ph*2;
			
			this.view.m_background.x=pw;
			this.view.m_background.y=ph;
			this.view.m_background.width=w;
			this.view.m_background.height=h;
			
			this.testLayer.Refresh();
		}
		
		/**
		 * 地图数据改变
		 */
		private function MapPropertyChanged(e:ModelEvent):void{
			this.RefreshView();
		}
		
		//添加一个新节点
		private function NodeAddHandler(e:ModelEvent):void{
			RefreshNodeList();
		}
		
		//删除一个节点
		private function NodeRemoveHandler(e:ModelEvent):void{
			RefreshNodeList();
		}
		
		//刷新节点列表
		private function RefreshNodeList():void{
			//清理老的
			var itemView:Object;
			for (var i:int = 0; i < this.view.m_content.m_content.numChildren; i++) 
			{
				itemView=this.view.m_content.m_content.getChildAt(i);
				mediatorMap.unmediate(itemView);
			}
			this.view.m_content.m_content.removeChildren(0,-1,true);
			
			if(this.currentMap==null){
				return;
			}
			var ediatorNodeView:GComponent;
			var count:uint=this.currentMap.nodes.length;
			var nodeData:CollectionValue;
			var nodeType:uint;
			for (var index:int = 0; index < count; index++) 
			{
				nodeData=this.currentMap.nodes.GetAt(index) as CollectionValue;
				nodeType=nodeData.Get(Propertys.TYPE).GetValue();
				switch(nodeType)
				{
					case NodeTypes.PATH:
					{
						var pathView:UI_PathNodeView=UI_PathNodeView.createInstance();
						pathView.data=nodeData;
						this.view.m_content.m_content.addChild(pathView);
						if(nodeData.Get(Propertys.EDIATRO_MODE).GetValue()>0){
							if(ediatorNodeView==null){
								ediatorNodeView=pathView;
							}else{
								nodeData.Update(Propertys.EDIATRO_MODE,0);
							}
						}
						mediatorMap.mediate(pathView);
						break;
					}
					case NodeTypes.AREA:
					{
						var areaView:UI_AreaNodeView=UI_AreaNodeView.createInstance();
						areaView.data=nodeData;
						this.view.m_content.m_content.addChild(areaView);
						if(nodeData.Get(Propertys.EDIATRO_MODE).GetValue()>0){
							if(ediatorNodeView==null){
								ediatorNodeView=areaView;
							}else{
								nodeData.Update(Propertys.EDIATRO_MODE,0);
							}
						}
						mediatorMap.mediate(areaView);
						break;
					}
					case NodeTypes.IMAGE:
					{
						var imageView:UI_ImageNodeView=UI_ImageNodeView.createInstance();
						imageView.data=nodeData;
						this.view.m_content.m_content.addChild(imageView);
						mediatorMap.mediate(imageView);
						break;
					}
				 	case NodeTypes.TOWER:
					{
						var towerView:UI_TowerNodeView=UI_TowerNodeView.createInstance();
						towerView.data=nodeData;
						this.view.m_content.m_content.addChild(towerView);
						mediatorMap.mediate(towerView);
						break;
					}
					default:
					{
						throw new Error("未知节点类型！");
						break;
					}
				}
			}
			if(ediatorNodeView!=null){
				this.view.m_content.m_content.addChild(ediatorNodeView);
			}
		}
		
		private function MenuCallBack(e:Event):void{
			var op:String=e.target.data.@value;
			if(op==null||op==""){
				return;
			}
			if(!this.project.currentMap){
				return;
			}
			if(op==Operations.NEW_NODE){
				var root:GRoot=this.view.root;
				var window:NewNodeWindow=new NewNodeWindow();
				window.showOn(root);
				window.centerOn(root);
				window.view.data=this.view.globalToLocal(this.view.displayObject.mouseX,this.view.displayObject.mouseY);
				mediatorMap.mediate(window);
			}else{
				this.project.undoSystem.executeOperation(op,e.target.data);
			}
		}
		
		private function ShowMenu(x:Number,y:Number):void{
			var xml:XML=<item/>
			var newNode:XML=<item/>;
			newNode.@label="新建节点";
			newNode.@value=Operations.NEW_NODE;
			
			xml.appendChild(newNode);
			if(this.rightMenu){
				this.rightMenu.removeAllItems();
			}
			this.rightMenu=MenuHelper.createByXML(xml,this.rightMenu);
			this.rightMenu.addEventListener(Event.SELECT,MenuCallBack);
			this.rightMenu.display(stage,x,y);
		}
	}
}